﻿using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Management;

namespace LotroData
{
    /// <summary>
    /// Contains methods for Encrypting and Decrypting strings using the Motherboard serial number as a key.
    /// </summary>
    internal static class CryptoService
    {
        private static readonly byte[] IVector = new byte[8] { 100, 42, 56, 74, 123, 87, 23, 53 };

        /// <summary>
        /// Gets the motherboard serial number for use in encryption.
        /// </summary>
        /// <returns></returns>
        private static string GetMoboSerial()
        {
            var srch = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard");
            var mObjs = srch.Get();

            foreach (var obj in mObjs)
            {
                return obj["SerialNumber"].ToString();
            }
            return null;
        }

        /// <summary>
        /// Encrypts the specified string.
        /// </summary>
        /// <param name="str">A <see cref="System.String"/> value to encrypt.</param>
        /// <returns>The encrypted <see cref="System.String"/> value.</returns>
        public static string Encrypt(this string str)
        {
            var buffer = Encoding.ASCII.GetBytes(str);
            var tripleDES = new TripleDESCryptoServiceProvider();
            var md5 = new MD5CryptoServiceProvider();

            tripleDES.Key = md5.ComputeHash(Encoding.ASCII.GetBytes(GetMoboSerial()));
            tripleDES.IV = IVector;

            var transform = tripleDES.CreateEncryptor();

            return Convert.ToBase64String(transform.TransformFinalBlock(buffer, 0, buffer.Length));
        }

        /// <summary>
        /// Decrypts the supplied string.
        /// </summary>
        /// <param name="str">A <see cref="System.String"/> value to decrypt.</param>
        /// <returns>The unencrypted <see cref="System.String"/> value.</returns>
        public static string Decrypt(this string str)
        {
            var buffer = Convert.FromBase64String(str);
            var tripleDes = new TripleDESCryptoServiceProvider();
            var MD5 = new MD5CryptoServiceProvider();

            tripleDes.Key = MD5.ComputeHash(Encoding.ASCII.GetBytes(GetMoboSerial()));
            tripleDes.IV = IVector;

            var ITransform = tripleDes.CreateDecryptor();

            return Encoding.ASCII.GetString(ITransform.TransformFinalBlock(buffer, 0, buffer.Length));
        }
    }
}
